//
//  RootViewController.m
//  UI14_数据解析
//
//  Created by dllo on 15/11/26.
//  Copyright (c) 2015年 dllo. All rights reserved.
//

#import "RootViewController.h"
#import "Student.h"
#import "GDataXMLNode.h"
#import "JSONKit.h"

@interface RootViewController ()<NSXMLParserDelegate>

@property (nonatomic, retain) NSMutableArray *stuArr;
@property (nonatomic, retain) NSString *elementStr;

@end

@implementation RootViewController

- (void)dealloc
{
    [_stuArr release];
    [_elementStr release];
    [super dealloc];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.view.backgroundColor = [UIColor greenColor];
    
    UIButton *buttonSax = [UIButton buttonWithType:UIButtonTypeCustom];
    buttonSax.frame = CGRectMake(50, 100, 100, 50);
    buttonSax.backgroundColor = [UIColor cyanColor];
    [buttonSax setTitle:@"XML/SAX" forState:UIControlStateNormal];
    [buttonSax addTarget:self action:@selector(saxAction) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:buttonSax];
    
    UIButton *buttonDom = [UIButton buttonWithType:UIButtonTypeCustom];
    buttonDom.frame = CGRectMake(50, 200, 100, 50);
    buttonDom.backgroundColor = [UIColor cyanColor];
    [buttonDom setTitle:@"XML/DOM" forState:UIControlStateNormal];
    [buttonDom addTarget:self action:@selector(domAction) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:buttonDom];
    
    UIButton *buttonJson = [UIButton buttonWithType:UIButtonTypeCustom];
    buttonJson.frame = CGRectMake(50, 300, 100, 50);
    buttonJson.backgroundColor = [UIColor cyanColor];
    [buttonJson setTitle:@"JSON" forState:UIControlStateNormal];
    [buttonJson addTarget:self action:@selector(jsonAction) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:buttonJson];
    
    
    
    
}

- (void)jsonAction
{
    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Student" ofType:@"txt"];
    // 二进制流, 安全
    NSData *data = [NSData dataWithContentsOfFile:filePath];
    
    // 参数1 : 读取到的二进制流
    // 参数2 : 转换为可变容器类型(如数组, 字典等)
    // 参数3 : 错误信息,若不需要可填nil
    NSMutableArray *arr = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
    NSLog(@"%@", arr);
    
    // 第三方解析
//    NSMutableArray *arr = [data objectFromJSONData];
    
    self.stuArr = [NSMutableArray array];
    for (NSMutableDictionary *dic in arr) {
        Student *stu = [[Student alloc] init];
        [stu setValuesForKeysWithDictionary:dic];
        [self.stuArr addObject:stu];
        [stu release];
    
    }
    // 打印信息(验证)
    for (Student *stu in self.stuArr) {
        NSLog(@"%@ %@ %@ %@",stu.name, stu.sex, stu.number, stu.phone);
    }
}

// DOM与SAX比较:
// DOM先将数据全部取到内存, 再解析, SAX逐行取数据并解析
// DOM更耗费内存, 不适合大数据解析, 但更加灵活, 可以解析获取指定行数据
// SAX不耗内存, 但不灵活, 只能逐行按顺序解析

- (void)domAction
{
    self.stuArr = [NSMutableArray array];
    
    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Student" ofType:@"xml"];
    // 二进制流, 安全
    NSData *data = [NSData dataWithContentsOfFile:filePath];
    
    // 添加路径:building settings -> Header Search Paths -> 添加路径://usr/include/libxml2
    // 添加库:building Phases -> Link... 添加库libxml2.dylib或libxml2.tdb
    
    // 参数1: 从文件中读取的data对象
    // 参数2: 预留参数, 写0
    // 参数3: 错误信息, 若不需要可写nil
    GDataXMLDocument *xmlD = [[[GDataXMLDocument alloc] initWithData:data options:0 error:nil] autorelease];
    
    GDataXMLElement *xmlE = xmlD.rootElement;
//    NSLog(@"整体信息:%@", xmlE);
    
    for (GDataXMLElement *subXmlE in xmlE.children) {
//        NSLog(@"每名学生的信息:%@", subXmlE);
        
        // 创建学生对象
        Student *stu = [[Student alloc] init];
        
        for (GDataXMLElement *element in subXmlE.children) {
 //            NSLog(@"具体信息, 每一条信息,如名字,学号,性别,电话:%@", element);
            NSLog(@"标签:%@ 标签值:%@", element.name, element.stringValue);
            
            [stu setValue:element.stringValue forKey:element.name];
        }
        [self.stuArr addObject:stu];
        [stu release];
        
    }
    for (Student *stu in self.stuArr) {
        NSLog(@"%@ %@ %@ %@",stu.name, stu.sex, stu.number, stu.phone);
    }
    
}

- (void)saxAction
{
    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Student" ofType:@"xml"];
    // 二进制流, 安全
    NSData *data = [NSData dataWithContentsOfFile:filePath];
    
    NSXMLParser *parser = [[[NSXMLParser alloc] initWithData:data] autorelease];
    
    parser.delegate = self;
    
    // 开始解析
    [parser parse];
    
    
    
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
    NSLog(@"只解析结束标签:%@", elementName);
    // 防止已解析号的标签值被非预期的标签值覆盖
    self.elementStr = nil;
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    NSLog(@"解析标签值:%@", string);
    
    // 获取到正在编辑的学生对象
    Student *stu = self.stuArr.lastObject;
    
    // 为学生对象赋值
    if ([self.elementStr isEqualToString:@"name"]) {
        stu.name = string;
    }
    if ([self.elementStr isEqualToString:@"number"]) {
        stu.number = string;
    }
    if ([self.elementStr isEqualToString:@"sex"]) {
        stu.sex = string;
    }
    if ([self.elementStr isEqualToString:@"phone"]) {
        stu.phone = string;
    }
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
    NSLog(@"只解析开始标签:%@", elementName);
    
    // 可以全局访问开始标签
    self.elementStr = elementName;
    
    // 若开始标签是student, 创建学生对象并添加进数组
    if ([elementName isEqualToString:@"student"]) {
        Student *stu = [[Student alloc] init];
        [self.stuArr addObject:stu];
        [stu release];
    }
}

- (void)parserDidStartDocument:(NSXMLParser *)parser
{
    NSLog(@"开始解析");
    // 开辟数组空间
    self.stuArr = [NSMutableArray array];
}

- (void)parserDidEndDocument:(NSXMLParser *)parser
{
    NSLog(@"结束解析");
    for (Student *stu in self.stuArr) {
        NSLog(@"%@ %@ %@ %@",stu.name, stu.sex, stu.number, stu.phone);
    }
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end
